﻿# coding: utf-8

import wx

from wxFramework.Dialog import wxDialogCreateParticleModifier
from Editor.ParticleSystemEditor import CParticleEmitter
from Editor.ParticleSystemEditor import CParticleModifier

class wxPanelParticleSystem(wx.Panel):
    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id)
        
        self._CreateObjectTree()
        self._DefinePopupMenuId()
        
        boxSizer = wx.BoxSizer(wx.VERTICAL)
        boxSizer.Add(self._objTree, 1, wx.ALL|wx.EXPAND, border = 5)
        self.SetSizer(boxSizer)
                
    def _CreateObjectTree(self):
        self._objTree = wx.TreeCtrl(self, wx.NewId(), wx.DefaultPosition, wx.DefaultSize)
        
        il = wx.ImageList(IL.IMAGE_SMALL, IL.IMAGE_SMALL)
        self._bmpIdxFolderNormal = il.Add(IL.GetBitmap(IL.ID_IMAGE_FILE_FOLDER_CLOSE, IL.IMAGE_SMALL))
        self._bmpIdxFolderExpand = il.Add(IL.GetBitmap(IL.ID_IMAGE_FILE_FOLDER_OPEN, IL.IMAGE_SMALL))
        self._bmpIdxFile = il.Add(IL.GetBitmap(IL.ID_IMAGE_FILE_NORMAL, IL.IMAGE_SMALL))
        self._bmpIdxFileSel = il.Add(IL.GetBitmap(IL.ID_IMAGE_FILE_SELECTED, IL.IMAGE_SMALL))
        self._objTree.SetImageList(il)
        self._il = il       
        
        root = self._objTree.AddRoot(TD.PARTICLE_SYSTEM_OBJECT_LIST)
        self._objTree.SetItemImage(root, self._bmpIdxFolderNormal, wx.TreeItemIcon_Normal)
        self._objTree.SetItemImage(root, self._bmpIdxFolderExpand, wx.TreeItemIcon_Expanded)
        
        self._emitterItem = self._AddKindItem(root, TD.EMITTER_LIST)
        self._textureItem = self._AddKindItem(root, TD.TEXTURE)
        
        self._objTree.Expand(root)
        
        self._objTree.Bind(wx.EVT_RIGHT_DOWN, self._OnRightClickClient)
        self._objTree.Bind(wx.EVT_TREE_SEL_CHANGED, self._OnTreeSelChanged)    
        
    def _DefinePopupMenuId(self):
        self._idNew = wx.NewId()
        self._idLoad = wx.NewId()
        self._idSave = wx.NewId()
        self._idClose = wx.NewId()
        
        self._idAddEmitter = wx.NewId()
        self._idRemoveEmitter = wx.NewId()
        
        self._idAddParticleModifier = wx.NewId()
        self._idRemoveParticleModifier = wx.NewId()
        
        self._idAddEmitterModifier = wx.NewId()
        self._idRemoveEmitterModifier = wx.NewId()
        
        self.Bind(wx.EVT_MENU, self._OnMenuNew, id = self._idNew)
        self.Bind(wx.EVT_MENU, self._OnMenuLoad, id = self._idLoad)
        self.Bind(wx.EVT_MENU, self._OnMenuSave, id = self._idSave)
        self.Bind(wx.EVT_MENU, self._OnMenuClose, id = self._idClose)
        
        self.Bind(wx.EVT_MENU, self._OnMenuAddEmitter, id = self._idAddEmitter)
        self.Bind(wx.EVT_MENU, self._OnMenuRemoveEmitter, id = self._idRemoveEmitter)
        
        self.Bind(wx.EVT_MENU, self._OnMenuAddParticleModifier, id = self._idAddParticleModifier)
        self.Bind(wx.EVT_MENU, self._OnMenuRemoveParticleModifier, id = self._idRemoveParticleModifier)
        
        self.Bind(wx.EVT_MENU, self._OnMenuAddEmitterModifier, id = self._idAddEmitterModifier)
        self.Bind(wx.EVT_MENU, self._OnMenuRemoveEmitterModifier, id = self._idRemoveEmitterModifier)
        
    def _OnRightClickClient(self, e):
        menu = wx.Menu()

        menu.Append(self._idNew, TD.NEW_PARTICLE_SYSTEM)
        menu.Append(self._idLoad, TD.LOAD_PARTICLE_SYSTEM)
        menu.Append(self._idSave, TD.SAVE_PARTICLE_SYSTEM)  
        
        if PARTICLE_SYSTEM_EDITOR.IsEditing():
            pos = e.GetPosition()
            item, flags = self._objTree.HitTest(pos)
            if item:            
                self._objTree.SelectItem(item)
                item = self._objTree.GetSelection()
                parentItem = self._objTree.GetItemParent(item)
                if item == self._emitterItem:
                    menu.AppendSeparator()
                    menu.Append(self._idAddEmitter, TD.ADD_EMITTER)
                
                if parentItem == self._emitterItem:
                    menu.AppendSeparator()
                    menu.Append(self._idRemoveEmitter, TD.REMOVE_EMITTER)    
    
                nodeData = self._objTree.GetPyData(item)
                parentNodeData = self._objTree.GetPyData(parentItem)
                if nodeData == 'EmitterModifierList':
                    menu.AppendSeparator()
                    menu.Append(self._idAddEmitterModifier, TD.ADD_EMITTER_MODIFIER)
                    
                if parentNodeData == 'EmitterModifierList':
                    menu.AppendSeparator()
                    menu.Append(self._idRemoveEmitterModifier, TD.REMOVE_EMITTER_MODIFIER)
                    
                if nodeData == 'ParticleModifierList':
                    menu.AppendSeparator()
                    menu.Append(self._idAddParticleModifier, TD.ADD_PARTICLE_MODIFIER)
                
                if parentNodeData == 'ParticleModifierList':
                    menu.AppendSeparator()
                    menu.Append(self._idRemoveParticleModifier, TD.REMOVE_PARTICLE_MODIFIER)

        self._objTree.PopupMenu(menu)
        menu.Destroy()         
        
    def _OnTreeSelChanged(self, e):
        item = e.GetItem()
        nodeData = self._objTree.GetPyData(item)

        if isinstance(nodeData, CParticleEmitter):
            PANEL_PROPERTY.SetPanelProperty(PANEL_PROP_PARTICLE_EMITTER)
            PANEL_PROP_PARTICLE_EMITTER.SetEmitter(nodeData)
        elif isinstance(nodeData, CParticleModifier):
            PANEL_PROPERTY.SetPanelProperty(PANEL_PROP_MODIFIER)
            PANEL_PROP_MODIFIER.SetModifier(nodeData)
        elif item == self._textureItem:
            PANEL_PROPERTY.SetPanelProperty(PANEL_PROP_PARTICLE_TEXTURE)
            PANEL_PROP_PARTICLE_TEXTURE.UpdateParticleTextureInformation()
        else:
            PANEL_PROPERTY.SetPanelProperty(PANEL_PROP_NULL)

    def __Refresh(self):
        self._objTree.DeleteChildren(self._emitterItem)
        for i in xrange(0, len(PARTICLE_SYSTEM_EDITOR._emitterList)):
            emitter = PARTICLE_SYSTEM_EDITOR._emitterList[i]
            itemEmitter = self._AddItem(self._emitterItem, TD.PARTICLE_EMITTER)
            self._objTree.SetPyData(itemEmitter, emitter)
            
            itemEM = self._AddKindItem(itemEmitter, TD.EMITTER_MODIFIER)
            self._objTree.SetPyData(itemEM, 'EmitterModifierList')
            itemPM = self._AddKindItem(itemEmitter, TD.PARTICLE_MODIFIER)
            self._objTree.SetPyData(itemPM, 'ParticleModifierList')
            
            for pmod in emitter._particleModifierList:
                item = self._AddItem(itemPM, pmod._name)
                self._objTree.SetPyData(item, pmod)
            
        self._objTree.ExpandAllChildren(self._emitterItem)

    def _OnMenuNew(self, e):
        newParticleSystem = True
        if PARTICLE_SYSTEM_EDITOR.IsEditing():
            msgDlg = wx.MessageDialog(self, TD.NEW_PARTICLE_SYSTEM_NOTIFY, '', wx.YES_NO|wx.ICON_INFORMATION)
            if msgDlg.ShowModal() != wx.ID_YES:
                newParticleSystem = False
            msgDlg.Destroy()
        
        if newParticleSystem:        
            PARTICLE_SYSTEM_EDITOR.New()
        
    def _OnMenuLoad(self, e):
        pass
        
    def _OnMenuSave(self, e):
        pass
        
    def _OnMenuClose(self, e):
        pass
        
    def _OnMenuAddEmitter(self, e):
        if not PARTICLE_SYSTEM_EDITOR.IsEditing():
            return
            
        if not PARTICLE_SYSTEM_EDITOR.AddEmitter():
            dlgMsg = wx.MessageDialog(self, TD.ERR_CREATE_PARTICLE_EMITTER_FAILED, TD.ERROR, wx.OK|wx.ICON_INFORMATION)
            dlgMsg.ShowModal()
            dlgMsg.Destroy()
            return
            
        self.__Refresh()
        
    def _OnMenuRemoveEmitter(self, e):
        if not PARTICLE_SYSTEM_EDITOR.IsEditing():
            return
            
        item = self._objTree.GetSelection()
        emitter = self._objTree.GetPyData(item)
        if not emitter:
            return
        
        if not PARTICLE_SYSTEM_EDITOR.RemoveEmitter(emitter):
            dlgMsg = wx.MessageDialog(self, TD.ERR_REMOVE_PARTICLE_EMITTER_FAILED, TD.ERROR, wx.OK|wx.INFORMATION)
            dlgMsg.ShowModal()
            dlgMsg.Destroy()
            
        self.__Refresh()
        
    def _OnMenuAddParticleModifier(self, e):
        if not PARTICLE_SYSTEM_EDITOR.IsEditing():
            return

        dlg = wxDialogCreateParticleModifier(self)
        dlg.CenterOnScreen()
        if dlg.ShowModal() != wx.ID_OK:
            dlg.Destroy()
            return
            
        modifierType = dlg.GetModifierType()
        dlg.Destroy()
        
        item = self._objTree.GetSelection()
        parentItem = self._objTree.GetItemParent(item)
        emitter = self._objTree.GetPyData(parentItem)
        if not emitter:
            return
            
        if not emitter.AddParticleModifier(modifierType):
            dlgMsg = wx.MessageDialog(self, TD.ERR_CREATE_PARTICLE_MODIFIER_FAILED, TD.ERROR, wx.OK|wx.ICON_INFORMATION)
            dlgMsg.ShowModal()
            dlgMsg.Destroy()
            return
            
        self.__Refresh()         
        
    def _OnMenuRemoveParticleModifier(self, e):
        if not PARTICLE_SYSTEM_EDITOR.IsEditing():
            return
            
        item = self._objTree.GetSelection()
        modifier = self._objTree.GetPyData(item)
        if not modifier:
            return
        
        emitter = modifier._emitterRef()
        if not emitter:
            return
            
        if not emitter.RemoveParticleModifier(modifier):
            dlgMsg = wx.MessageDialog(self, TD.ERR_REMOVE_PARTICLE_MODIFIER_FAILED, TD.ERROR, wx.OK|wx.INFORMATION)
            dlgMsg.ShowModal()
            dlgMsg.Destroy()
            
        self.__Refresh()
        
    def _OnMenuAddEmitterModifier(self, e):
        pass
        
    def _OnMenuRemoveEmitterModifier(self, e):
        pass
        
    def _AddKindItem(self, parentItem, text):
        item = self._objTree.AppendItem(parentItem, text)
        self._objTree.SetItemImage(item, self._bmpIdxFolderNormal, wx.TreeItemIcon_Normal)
        self._objTree.SetItemImage(item, self._bmpIdxFolderExpand, wx.TreeItemIcon_Expanded)
        return item

    def _AddItem(self, kinditem, text):
        item = self._objTree.AppendItem(kinditem, text)
        self._objTree.SetItemImage(item, self._bmpIdxFile, wx.TreeItemIcon_Normal)
        self._objTree.SetItemImage(item, self._bmpIdxFileSel, wx.TreeItemIcon_Selected)
        return item        